package com.towexin.config.shiro;

import com.towexin.application.system.domain.Authority;
import com.towexin.application.system.domain.Role;
import com.towexin.application.system.domain.User;
import com.towexin.application.system.service.AuthorityService;
import com.towexin.application.system.service.RoleService;
import com.towexin.application.system.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * TODO
 * 自定义Realm，实现Shiro认证
 *
 * @author Towexin
 * @version 1.0
 * @date 2020/11/24 16:58
 */

@Component
public class ShiroRealm extends AuthorizingRealm {
    private static final Logger logger = LoggerFactory.getLogger(AuthorizingRealm.class);

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private AuthorityService authorityService;

    /**
     * 用户授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        logger.info("********用户授权********");

        SimpleAuthorizationInfo info= new SimpleAuthorizationInfo();

        String username= principalCollection.toString();

        // 判断用户被冻结
        if (!userService.selectByUserName(username).getStatus()) throw new UnknownAccountException("userLoginLock");

        // 配置权限
        Set<String> Permissions = new HashSet<>(authorityService.selectMarkAndDefaultRoleByUserName(username));
        info.setStringPermissions(Permissions);

        // 配置角色
        Set<String> roles = new HashSet<>(roleService.getRoleAndDefaultMarkByUserName(username));
        info.setRoles(roles);

        return info;
    }

    /**
     * 用户身份认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String) authenticationToken.getPrincipal();

        logger.info("********身份认证********, username={}", username);

        User user = userService.selectByUserName(username);
        if (user != null) {
            // 使用了 验证器，增加了登录次数校验功能，此项无需再配
            //String password = new String((char[]) authenticationToken.getCredentials());
            //if(user.getPassword().equals(password)){
            //    return new SimpleAuthenticationInfo(user.getUsername(), password, getName());
            //}else {
            //    throw new IncorrectCredentialsException("passwordError");
            //}
            if (!user.getStatus()) throw new UnknownAccountException("userLock");
            return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
        } else {
            throw new UnknownAccountException("noUser");
        }
    }
}
